﻿#region Copyright

// <copyright company="CSZI.com">
// ------------------------------------------------------------------------------
// Copyright (c) 2002-2010 Chaos Studio.  All rights reserved.
// Contact   :   MSN:zhouyu@cszi.com , QQ:478779122 .
// Link         :   http://www.CSZI.com , http://www.69sea.com
// Author     :   zhouyu(周宇)
// ------------------------------------------------------------------------------
// </copyright>

#endregion

using System;
using System.Data;
using System.IO;
using System.Text;
using CS.Data;
using CS.TaskScheduling;
using log4net;

namespace CS.Task.DataTransfer
{
    /// <summary>
    /// 从数据库中一个表导入另一个数据的一个表中，并备份一些相关数据
    /// </summary>
    ///
    /// <description class = "CS.Task.DataTransfer.DataImporter">  
    /// </description> 
    ///
    /// <history>
    /// Create      :	atwind , 2010-5-31 19:06:42 ;
    ///  </history>
    public class DataTableToDataTable : TaskProvider
    {
        private static readonly ILog workLog = LogManager.GetLogger();

        /// <summary>
        /// 取得要导入的数据表
        /// </summary>
        /// <returns></returns>
        public DataTable FetchTable()
        {
            RefInfo res = Extend.Refs["originDb"];
            if (res == null)
            {
                workLog.ErrorFormat("未找到源数据库的配置，无法执行数据获取，请检查配置文件Tasks.config。");
                return null;
            }
            string connstring = res.Resource.Value;
            string sql = res.Params["Execute"].Value;
            DataSet ds = SqlHelper.ExecuteDataset(connstring, CommandType.Text, sql);
            return ds.Tables[0];
        }

        /// <summary>
        /// 导入数据
        /// </summary>
        /// <param name="sourceData">将被导入的数据</param>
        /// <returns>导入的数量</returns>
        public int ImportData(DataTable sourceData)
        {
            if (sourceData == null) return 0;
            RefInfo res = Extend.Refs["destinationDb"];
            if(res == null)
            {
                workLog.ErrorFormat("未找到目标数据库的配置，无法执行导入功能，请检查配置文件Tasks.config。");
                return 0;
            }
            string connstring = res.Resource.Value;
            string preSql = res.Params["Prepare"].Value;     //准备
            string execSql = res.Params["Execute"].Value;   //执行
            string windUp = res.Params["WindUp"].Value;    //收尾
            var sb = new StringBuilder();
            if(!string.IsNullOrEmpty(preSql)) sb.AppendLine(preSql);
            foreach (DataRow row in sourceData.Rows)
            {
                sb.AppendFormat(execSql, row[0], row[1], row[2], row[3], row[4], row[5], row[6]);
            }
            if (!string.IsNullOrEmpty(windUp)) sb.AppendLine(windUp);
            int val = SqlHelper.ExecuteNonQuery(connstring, CommandType.Text, sb.ToString());
            return val;
        }

        /// <summary>
        /// 数据备份
        /// </summary>
        /// <returns></returns>
        public bool BackupData()
        {
            var rdb = Extend.Refs["destinationDb"];
            if (rdb == null) return false;
            var r = Extend.Refs["backupToFile"];
            if (r == null) return false;
            string connstring = rdb.Resource.Value;
            string fileNamePat = AppDomain.CurrentDomain.BaseDirectory + "\\" + r.Resource.Value;
            ParamCollection sqls = r.Params;
            DateTime now = DateTime.Now;
            foreach (ParamInfo sql in sqls)
            {
                string fileName = string.Format(fileNamePat, now, sql.Key);
                string path = fileName.Substring(0, fileName.LastIndexOf(@"\"));
                DataTable dt = SqlHelper.ExecuteDataset(connstring, CommandType.Text, sql.Value).Tables[0];
                if (dt == null) continue;
                int colMax = dt.Columns.Count;
                var sb = new StringBuilder();
                foreach (DataRow row in dt.Rows)
                {
                    string newLine = "";
                    for (int i = 0; i < colMax; i++)
                    {
                        newLine += row[i] + "\t";
                    }
                    sb.AppendLine(newLine);
                }
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                if (!File.Exists(fileName))
                {
                    Encoding fileEncoding = Encoding.Default;
                    using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
                    {
                        using (var sw = new StreamWriter(fs, fileEncoding))
                        {
                            sw.Write(sb);
                            sw.Flush();
                            sw.Dispose();
                        }
                        fs.Dispose();
                    }
                }
            }
            return true;
        }

        #region TaskProvider 的实现

        /// <summary>
        /// 任务入口
        /// </summary>
        /// <returns></returns>
        protected override Result Work()
        {
            var rst = new Result();
            DataTable dt = FetchTable();
            int cols = ImportData(dt);
            if (cols > 0)
            {
                var val = BackupData();
                rst.Stamp = ResultType.Succeed;
                rst.Message += string.Format("成功导入了{0}条数据到目标数据库", cols);
                workLog.InfoFormat(rst.Message);
                if(val)
                {
                    workLog.InfoFormat("数据备份成功");
                }
                else
                {
                    workLog.WarnFormat("备份功能未启用或备份失败！");
                }
            }
            else
            {
                rst.Stamp = ResultType.Failed;
                rst.Message += string.Format("没有可导入的数据");
            }

            return rst;
        }

        #endregion
    }
}